package cn.pli.femedia;
/**
 * fast edit media
 * 使用gpu 快速对视频文件进行处理
 */

import android.app.Activity;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.SurfaceTexture;
import android.os.Build;
import android.os.Environment;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.Spinner;

import java.io.File;
import java.io.IOException;

import cn.pli.femedia.egl.GLES20BackEnv;
import cn.pli.femedia.video.EncoderConfig;
import cn.pli.femedia.video.VideoRecordRender;

public class MainActivity extends Activity implements AdapterView.OnItemSelectedListener,
        MoviePlayer.PlayerFeedback {
    private static final String TAG = "MainActivity.TAG";
    private TextureView mTextureView;
    private String[] mMovieFiles;
    private int mSelectedMovie;
    private boolean mShowStopLabel;
    private MoviePlayer.PlayTask mPlayTask;
    private boolean mSurfaceTextureReady = true;
    private final Object mStopper = new Object();   // used to signal stop
    public static VideoEncoderCore encoderCore;
    public static boolean isEncoder = true;
    public static VideoRecordRender mVideoRecordRender;
    private GLES20BackEnv gles20BackEnv;
    public static Handler mHandler;
    public static final int ON_DRAW_FRAME = 10;         //编译帧
    public static final int STOP_RECOEDING = 11;        //结束编码

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextureView = (TextureView) findViewById(R.id.movie_texture_view);
        // mTextureView.setSurfaceTextureListener(this);
        Spinner spinner = (Spinner) findViewById(R.id.playMovieFile_spinner);
        mMovieFiles = MiscUtils.getFiles(Environment.getExternalStorageDirectory(), "*.mp4");
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item, mMovieFiles);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);
        spinner.setOnItemSelectedListener(this);
        updateControls();
        EncoderConfig encoderConfig = new EncoderConfig(360, 640, 512 * 1024);
        mVideoRecordRender = new VideoRecordRender(this, encoderConfig);

        mHandler = new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                int i = msg.what;
                switch (i) {
                    case ON_DRAW_FRAME:
                        Log.d(TAG, "ON_DRAW_FRAME:" + ON_DRAW_FRAME);
                        mVideoRecordRender.onDrawFrame();
                        break;
                    case STOP_RECOEDING:
                        mVideoRecordRender.setRecordingEnabled(false);
                        mVideoRecordRender.onDrawFrame();
                        break;
                }
                return false;
            }
        });
    }


    /*
     * Called when the movie Spinner gets touched.
     */
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
        Spinner spinner = (Spinner) parent;
        mSelectedMovie = spinner.getSelectedItemPosition();
        Log.d(TAG, "onItemSelected: " + mSelectedMovie + " '" + mMovieFiles[mSelectedMovie] + "'");
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
    }

    /**
     * onClick handler for "play"/"stop" button.
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public void clickPlayStop(@SuppressWarnings("unused") View unused) {
        if (mShowStopLabel) {
            stopPlayback();
        } else {
            if (mPlayTask != null) {
                Log.w(TAG, "movie already playing");
                return;
            }
            Log.d(TAG, "starting movie");
            SpeedControlCallback callback = new SpeedControlCallback();
            if (((CheckBox) findViewById(R.id.locked60fps_checkbox)).isChecked()) {
                callback.setFixedPlaybackRate(100);
            }
            MoviePlayer player = null;
            try {
                player = new MoviePlayer(new File(Environment.getExternalStorageDirectory(), mMovieFiles[mSelectedMovie]), callback);
            } catch (IOException ioe) {
                Log.e(TAG, "Unable to play movie", ioe);
                return;
            }

            //创建后台opengl环境
            Surface surface = setGLEnv(player.getVideoSize().getWidth(),player.getVideoSize().getHeight());


            player.setmOutputSurface(surface);
            mPlayTask = new MoviePlayer.PlayTask(player, this);
            if (((CheckBox) findViewById(R.id.loopPlayback_checkbox)).isChecked()) {
                mPlayTask.setLoopMode(true);
            }
            mVideoRecordRender.setRecordingEnabled(true);
            mShowStopLabel = true;
            updateControls();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    mPlayTask.execute();
                }
            }).start();

        }
    }

    private Surface setGLEnv(int width,int height) {
        gles20BackEnv = new GLES20BackEnv(width, height);
        gles20BackEnv.setThreadOwner(getMainLooper().getThread().getName());

        mVideoRecordRender.onVideoSizeChanged(width, height);
        mVideoRecordRender.onEditVideoReady();
        mVideoRecordRender.setOriginalVideoSize(width, height);
        Surface surface = mVideoRecordRender.getmSurface();
        adjustAspectRatio(width, height);
        return surface;
    }

    /**
     * Requests stoppage if a movie is currently playing.  Does not wait for it to stop.
     */
    private void stopPlayback() {
        if (mPlayTask != null) {
            mPlayTask.requestStop();
        }
    }

    @Override   // MoviePlayer.PlayerFeedback
    public void playbackStopped() {
        Log.d(TAG, "playback stopped");
        mShowStopLabel = false;
        mPlayTask = null;
        updateControls();
    }

    /**
     * Sets the TextureView transform to preserve the aspect ratio of the video.
     */
    private void adjustAspectRatio(int videoWidth, int videoHeight) {
        int viewWidth = mTextureView.getWidth();
        int viewHeight = mTextureView.getHeight();
        double aspectRatio = (double) videoHeight / videoWidth;


        int newWidth, newHeight;
        if (viewHeight > (int) (viewWidth * aspectRatio)) {
            // limited by narrow width; restrict height
            newWidth = viewWidth;
            newHeight = (int) (viewWidth * aspectRatio);
        } else {
            // limited by short height; restrict width
            newWidth = (int) (viewHeight / aspectRatio);
            newHeight = viewHeight;
        }
        int xoff = (viewWidth - newWidth) / 2;
        int yoff = (viewHeight - newHeight) / 2;
        Log.v(TAG, "video=" + videoWidth + "x" + videoHeight +
                " view=" + viewWidth + "x" + viewHeight +
                " newView=" + newWidth + "x" + newHeight +
                " off=" + xoff + "," + yoff);

        Matrix txform = new Matrix();
        mTextureView.getTransform(txform);
        txform.setScale((float) newWidth / viewWidth, (float) newHeight / viewHeight);
        txform.postTranslate(xoff, yoff);
        mTextureView.setTransform(txform);
    }

    /**
     * Updates the on-screen controls to reflect the current state of the app.
     */
    private void updateControls() {
        Button play = (Button) findViewById(R.id.play_stop_button);
        if (mShowStopLabel) {
            play.setText("停止");
        } else {
            play.setText("播放");
        }
        play.setEnabled(mSurfaceTextureReady);
        // We don't support changes mid-play, so dim these.
        CheckBox check = (CheckBox) findViewById(R.id.locked60fps_checkbox);
        check.setEnabled(!mShowStopLabel);
        check = (CheckBox) findViewById(R.id.loopPlayback_checkbox);
        check.setEnabled(!mShowStopLabel);
    }
}
